
#include <string>

template <typename T>
struct identity {
  typedef T type;
};

bool is_number(const std::string &s) {
  return !s.empty() && s.find_first_not_of("0123456789") == std::string::npos;
}

template <typename Q>
Q safe_convert(const std::string &res) {
  if (!is_number()) {
    std::cout << "[res convert fail]" << res << std::endl;
    return 0;
  }
  return convert(res, identity<Q>());
}

template <typename M>
double convert(const std::string &res, identity<M>) {
  printf("1");
  return 0;
}

float convert(const std::string &res, identity<double>) {
  printf("123");
  return 0;
}

int convert(const std::string &res, identity<int>) {
  printf("int");
  return 0;
}

int main(int argc, char *argv[]) {
  std::string num = "3.4";
  safe_convert<double>(num);
}